/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */




import java.awt.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Iterator;





import java.util.Random;

import junit.framework.TestCase;
//Team: Tuzzy Fester and the Testimonials 
//Sara Thorup
//Tom Lewis
//Becky Kluth


/**
 * Performs Validation Test for url validations.
 *
 * @version $Revision: 1128446 $ $Date: 2011-05-27 13:29:27 -0700 (Fri, 27 May 2011) $
 */
public class UrlValidatorTest extends TestCase {

   private boolean printStatus = false;
   private boolean printIndex = false;//print index that indicates current scheme,host,port,path, query test were using.

   public UrlValidatorTest(String testName) {
      super(testName);
   }

   
   
   public void testManualTest()
   {
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
	   
	   //Put the URL you want to test in this map.  Key = URL, Value = whether or not it is a valid URL
	   Map<String, Boolean> testURLs = new LinkedHashMap<String, Boolean>();
	   testURLs.put("http://www.amazon.com", true);
	   testURLs.put("https://w!!!!ww.amazon.com", false);
	   testURLs.put("https://www.amazon.com", true);
	   testURLs.put("http:/www.amazon.com", false);
	   testURLs.put("http://www.google.hk", true);
	   testURLs.put("http://www.google.it", true);
	   testURLs.put("http://www.google.jp", true);  //BUG
	   testURLs.put("http://www.google.zw", true);  //BUG
	   testURLs.put("http://localhost:ham", false); 
	   testURLs.put("http://localhost:80", true);//BUG
	   testURLs.put("http://www.google.com/?ham=true", true); //BUG
	   testURLs.put("http://www.google.com/cse?cx=012652&wv=1013", true); //BUG
	   testURLs.put("http://www.google.com/news/local.html?city=seattle", true); //BUG
	   
	   //Iterators through the URLs and checks to see if we got the expected value
	   Iterator<Entry<String, Boolean>> urlIterator = testURLs.entrySet().iterator();
	   while (urlIterator.hasNext()) {
		   Map.Entry<String, Boolean> pairs = (Map.Entry<String, Boolean>)urlIterator.next();
		   boolean result = urlVal.isValid(pairs.getKey());
		   boolean expected = pairs.getValue();
		   
		   //If they don't match the URL is displayed in the Junit sidebar
		   assertEquals(pairs.getKey(), expected, result);
		   
	   }
	   
   }
   
   /*
    * Testing within the partition "http://"
    */
   public void testYourFirstPartition()
   {
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
	   
	   //Put the URL you want to test in this map.  Key = URL, Value = whether or not it is a valid URL
	   Map<String, Boolean> testURLs = new LinkedHashMap<String, Boolean>();
	   testURLs.put("http://www.amazon.com", true);
	   testURLs.put("http://go.com", true);
	   testURLs.put("http://255.255.255.255", true);
	   testURLs.put("http://256.256.256.256", false);     //FIXED BUG
	   testURLs.put("http://1.2.3", false);
	   testURLs.put("http://www.amazon.com:80", true);
       testURLs.put("http://www.amazon.com:65535", true); //BUG
	   testURLs.put("http://www.amazon.com:0", true);
	   testURLs.put("http://www.amazon.com:-1", false); 
	   testURLs.put("http://www.amazon.com:65636", false); 
	   testURLs.put("http://www.amazon.com:65a", false);  
	    
	   //Iterators through the URLs and checks to see if we got the expected value
	   Iterator<Entry<String, Boolean>> urlIterator = testURLs.entrySet().iterator();
	   while (urlIterator.hasNext()) {
		   Map.Entry<String, Boolean> pairs = (Map.Entry<String, Boolean>)urlIterator.next();
		   boolean result = urlVal.isValid(pairs.getKey());
		   boolean expected = pairs.getValue();
		   
		   //If they don't math the URL is displayed in the Junit sidebar
		   assertEquals(pairs.getKey(), expected, result);
		   
	   }

   }
   
   
   /*
    * Testing within the partition "ftp://"
    */
   public void testYourSecondPartition(){
 UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
	   
	   //Put the URL you want to test in this map.  Key = URL, Value = whether or not it is a valid URL
	   Map<String, Boolean> testURLs = new LinkedHashMap<String, Boolean>();
	   testURLs.put("ftp://www.amazon.com", true);
	   testURLs.put("ftp://go.com", true);
	   testURLs.put("ftp://255.255.255.255", true);		 //Fixed BUG
	   testURLs.put("ftp://256.256.256.256", false);     //Fixed BUG
	   testURLs.put("ftp://1.2.3", false);
	   testURLs.put("ftp://www.amazon.com:80", true);
       testURLs.put("ftp://www.amazon.com:65535", true); //BUG
	   testURLs.put("ftp://www.amazon.com:0", true);
	   testURLs.put("ftp://www.amazon.com:-1", false); 
       testURLs.put("ftp://www.amazon.com:65636", true);  //BUG
	   testURLs.put("ftp://www.amazon.com:65a", false);  
	   
	   //Iterators through the URLs and checks to see if we got the expected value
	   Iterator<Entry<String, Boolean>> urlIterator = testURLs.entrySet().iterator();
	   while (urlIterator.hasNext()) {
		   Map.Entry<String, Boolean> pairs = (Map.Entry<String, Boolean>)urlIterator.next();
		   boolean result = urlVal.isValid(pairs.getKey());
		   boolean expected = pairs.getValue();
		   
		   //If they don't math the URL is displayed in the Junit sidebar
		   assertEquals(pairs.getKey(), expected, result);
		   
	   }
   }
   
   ResultPair[] testUrlScheme = {
		   new ResultPair("http://", true),
           new ResultPair("ftp://", true),
           new ResultPair("h3t://", true),
           new ResultPair("3ht://", false),
           new ResultPair("http:/", false),
           new ResultPair("http:", false),
           new ResultPair("http/", false),
           new ResultPair("://", false),
           new ResultPair("", true)
   };
   
   
   
   public void testIsValid()
   {
	   

	   boolean expected;
	   Random random = new Random();
	      
	   //load test data
	   
	   //schemes
	   Map<String, Boolean> schemes = new LinkedHashMap<String, Boolean>();	   
	   schemes.put("http://", true);
	   schemes.put("3hp://", false);
	   schemes.put("h3t://", true);
	   schemes.put("3ht://", false);
	   schemes.put("http:/", false);
	   schemes.put("http:", false);       
	   schemes.put("http/", false);
	   schemes.put("://", false);
	   schemes.put("", true);	  //BUG
	   
	  
	   //addresses
	   Map<String, Boolean> addresses = new LinkedHashMap<String, Boolean>();
	   addresses.put("www.amazon.com", true);
	   addresses.put("go.au", true);
       addresses.put("0.0.0.0", true);
       addresses.put("255.255.255.255", true);	 //Fixed BUG
       addresses.put("256.256.256.256", false);	 //Fixed BUG
       addresses.put("255.com", true);
       addresses.put("1.2.3.4.5", false);
       addresses.put("1.2.3.4.", false);
       addresses.put("1.2.3", false);
       addresses.put(".1.2.3.4", false);
       addresses.put("go.a", false);
       addresses.put("go.a1a", false);
       addresses.put("go.cc", true);
       addresses.put("go.1aa", false);
       addresses.put("aaa.", false);
       addresses.put(".aaa", false);
       addresses.put("aaa", false);
       addresses.put("", false);
	   
	   
	   //ports
	   Map<String, Boolean> ports = new LinkedHashMap<String, Boolean>();
	   ports.put(":80", true);
       ports.put(":65535", true);   //BUG
       ports.put(":0", true);
       ports.put("", true);
       ports.put(":-1", false);
       ports.put(":65636", false);
       ports.put(":65a", false);
	   
	   //paths
	   Map<String, Boolean> paths = new LinkedHashMap<String, Boolean>();
	   paths.put("/test1", true);
       paths.put("/t123", true);
       paths.put("/$23", true);
       paths.put("/..", false);
       paths.put("/../", false);
       paths.put("/test1/", true);
       paths.put("", true);
       paths.put("/test1/file", true);
       paths.put("/..//file", false);
       paths.put("/test1//file", false);
	   
	   //build lists of keys
	   ArrayList<String> schemeKeys = new ArrayList<String>(schemes.keySet());
	   ArrayList<String> addrKeys = new ArrayList<String>(addresses.keySet());
	   ArrayList<String> portKeys = new ArrayList<String>(ports.keySet());
	   ArrayList<String> pathKeys = new ArrayList<String>(paths.keySet());
	   
	   
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES); 
	   
	   for(int i = 0;i<10000;i++)
	   {
		   
		   String randomScheme = schemeKeys.get( random.nextInt(schemeKeys.size()) ); //get random scheme
		   String randomAddr = addrKeys.get( random.nextInt(addrKeys.size()) ); //get random address
		   String randomPort = portKeys.get( random.nextInt(portKeys.size()) ); //get random port
		   String randomPath = pathKeys.get( random.nextInt(pathKeys.size()) ); //get random path
		 
		   //build test url
		   String testString = randomScheme;
		   expected = schemes.get(randomScheme);
		   
		   testString += randomAddr;
		   expected = expected & addresses.get(randomAddr);
		   
		   testString += randomPort;
		   expected = expected & ports.get(randomPort);
		   
		   testString += randomPath;
		   expected = expected & paths.get(randomPath);
		   
		   boolean result = urlVal.isValid(testString);
		   
		   System.out.println("url:"+ testString+ " val: "+ expected); 
           assertEquals( expected, result); 
 
	   }
	      
	   
   }
   
   public void testAnyOtherUnitTest()
   {
	   
   }
   /**
    * Create set of tests by taking the testUrlXXX arrays and
    * running through all possible permutations of their combinations.
    *
    * @param testObjects Used to create a url.
    */
   

}
